package com.zxy.study.ui.photoview;

import android.util.Log;
import android.view.MotionEvent;

/**
 * Created by willy on 2017/11/22.
 */

public class RotateGestureDetector implements IRotateDetector{

    private int mLastAngle = 0;
    private IRotateListener mListener;
    private boolean mIsRotate;

    /**
     * set rotation listener for callback
     *
     * @param listener a  rotation listener
     */
    public void setRotateListener(IRotateListener listener) {
        this.mListener = listener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return doRotate(event);
    }

    @Override
    public boolean isRotating() {
        return mIsRotate;
    }

    /**
     * handle rotation
     *
     * @param ev Motion event
     * @return always true.
     */
    private boolean doRotate(MotionEvent ev) {
        if (ev.getPointerCount() != 2) {
            return false;
        }
        //Calculate the angle between the two fingers
        int pivotX = (int) (ev.getX(0) + ev.getX(1)) / 2;
        int pivotY = (int) (ev.getY(0) + ev.getY(1)) / 2;
        float deltaX = ev.getX(0) - ev.getX(1);
        float deltaY = ev.getY(0) - ev.getY(1);

        double radians = Math.atan(deltaY / deltaX);
        //Convert to degrees
      //  int degrees = (int) (radians * 180 / Math.PI);
    //    Log.v("dyp","ev.getX(0):"+ev.getX(0)+",ev.getY(0):"+ev.getY(0)+",ev.getX(1):"+ev.getX(1)+",ev.getY(1):"+ev.getY(1));
    //    Log.v("dyp","degress:"+degrees+",deltay:"+deltaY+",deltaX:"+deltaX+",deltaY/deltaX:"+(deltaY/deltaX));
        int degrees = (int) Math.round(Math.toDegrees(Math.atan2(deltaY,deltaX)));
        Log.v("dyp6","degrees:"+degrees);
        /*
         * Must use getActionMasked() for switching to pick up pointer events.
         * These events have the pointer index encoded in them so the return
         * from getAction() won't match the exact action constant.
         */
        switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mLastAngle = degrees;
                mIsRotate = false;
                break;
            case MotionEvent.ACTION_UP:
                mIsRotate = false;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                mLastAngle = degrees;
                mIsRotate = false;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_POINTER_UP:
                mIsRotate = false;
                upRotate(pivotX, pivotY);
                mLastAngle = degrees;
                break;
            case MotionEvent.ACTION_MOVE:
                mIsRotate = true;
                int degreesValue = degrees  - mLastAngle;
                Log.v("dyp1","degressValue:"+degreesValue);
                if (degreesValue > 45) {
                    //Going CCW across the boundary
                    rotate(-5, pivotX, pivotY);
                } else if (degreesValue < -45) {
                    //Going CW across the boundary
                    rotate(5, pivotX, pivotY);
                } else {
                    //Normal rotation, rotate the difference
                    rotate(degreesValue, pivotX, pivotY);
                }
                //Save the current angle
                mLastAngle = degrees;
                break;
        }
        return true;
    }

    /**
     * to invoke the callback
     *
     * @param degree degree to rotate
     */
    private void rotate(int degree, int pivotX, int pivotY) {
        if (mListener != null) {
            mListener.rotate(degree, pivotX, pivotY);
        }
    }

    /**
     * to invoke the finger up action
     */
    private void upRotate(int pivotX, int pivotY) {
        if (mListener != null) {
            mListener.upRotate(pivotX, pivotY);
        }
    }


}
